package bootstrapper

import (
	"baokaobang/controllers"
	"baokaobang/controllers/admin"
	"baokaobang/controllers/chat"
	"baokaobang/datasourse"
	"baokaobang/models"
	"baokaobang/utils"
	"fmt"
	"strings"
	"time"

	"github.com/iris-contrib/middleware/cors"
	"github.com/kataras/iris/v12"
	"github.com/kataras/iris/v12/mvc"
	"github.com/kataras/iris/v12/sessions"
	"github.com/kataras/iris/v12/websocket"
)

var sess = sessions.New(sessions.Config{
	Cookie:  "bkbsessionid",
	Expires: 240 * time.Hour,
})

type Bootstrapper struct {
	*iris.Application
}

func New() *Bootstrapper {
	return &Bootstrapper{
		Application: iris.New(),
	}
}

func (b *Bootstrapper) Listen() {
	err := b.Run(iris.Addr(":8009"))
	if err != nil {
		b.Logger().Errorf("应用程序启动失败:%s", err.Error())
	}
}

func (b *Bootstrapper) InitRoutes() {
	b.Use(sess.Handler())

	// 允许跨域请求
	crs := cors.New(cors.Options{
		AllowedOrigins:   []string{"*"}, // 允许通过的主机名称
		AllowCredentials: true,
	})
	b.Use(crs)

	tmpl := iris.HTML("./views", ".html")
	// 模板文件改变时自动加载，开发时使用，生产环境不要用(设置为false)，因为会消耗掉不少的性能
	tmpl.Reload(true)
	b.RegisterView(tmpl)

	//b.HandleDir("/static", "./static")

	// 使用csrf
	/*protect := csrf.Protect([]byte("9AB0F421E53A477C084477AEA06096F5"),
	csrf.Secure(true))*/

	b.HandleDir("/static", "./static")

	api := b.Party("/api")
	{
		// 前端
		mvc.New(api.Party("/no-login")).Handle(new(controllers.NoLogin))                              // 所有不需要的接口
		mvc.New(api.Party("/upload")).Handle(new(controllers.UploadController))                       // 上传
		mvc.New(api.Party("/major", LoginAuth)).Handle(new(controllers.Major))                        // 专业查询
		mvc.New(api.Party("/rank", LoginAuth)).Handle(new(controllers.Rank))                          // 位次查询
		mvc.New(api.Party("/volunteer", LoginAuth)).Handle(new(controllers.Volunteer))                // 志愿检测
		mvc.New(api.Party("/feedback", LoginAuth)).Handle(new(controllers.Feedback))                  // 反馈，不用了
		mvc.New(api.Party("/expert", LoginAuth)).Handle(new(controllers.Expert))                      // 没用了
		mvc.New(api.Party("/trends", LoginAuth)).Handle(new(controllers.Trends))                      // 动态
		mvc.New(api.Party("/comment", LoginAuth)).Handle(new(controllers.Comment))                    // 动态评论
		mvc.New(api.Party("/thumbs-up", LoginAuth)).Handle(new(controllers.ThumbsUp))                 // 点赞
		mvc.New(api.Party("/user", LoginAuth)).Handle(new(controllers.User))                          // 会员相关
		mvc.New(api.Party("/enrollment", LoginAuth)).Handle(new(controllers.Enrollment))              // 招生计划（展示用）
		mvc.New(api.Party("/university", LoginAuth)).Handle(new(controllers.University))              // 大学
		mvc.New(api.Party("/enroll-profile", LoginAuth)).Handle(new(controllers.EnrollProfile))       // 招生简章
		mvc.New(api.Party("/enroll-plan", LoginAuth)).Handle(new(controllers.EnrollPlan))             // 招生计划
		mvc.New(api.Party("/major-probability", LoginAuth)).Handle(new(controllers.MajorProbability)) // 专业概率
		mvc.New(api.Party("/label", LoginAuth)).Handle(new(controllers.Label))                        // 用户标签
		mvc.New(api.Party("/pushMessage", LoginAuth)).Handle(new(controllers.GroupMessage))           //发送群消息
		mvc.New(api.Party("/checkGroupMembers", LoginAuth)).Handle(new(controllers.GroupMembers))     //获取群成员消息
		mvc.New(api.Party("/groupQuit", LoginAuth)).Handle(new(controllers.GroupQuit))                //退出群组
		mvc.New(api.Party("/groupSilence", LoginAuth)).Handle(new(controllers.GroupSilence))          //全员禁言
		// mvc.New(api.Party("/privateChat", LoginAuth)).Handle(new(controllers.PrivateChat))            //点击群成员进行私聊
		mvc.New(api.Party("/pay", LoginAuth)).Handle(new(controllers.Pay))                      //付款
		mvc.New(api.Party("/collectionCollege", LoginAuth)).Handle(new(controllers.Collection)) //收藏学校
		mvc.New(api.Party("/collectionMajor", LoginAuth)).Handle(new(controllers.Collection))
		mvc.New(api.Party("/cancelCollege", LoginAuth)).Handle(new(controllers.Cancel)) //取消收藏学校
		mvc.New(api.Party("/cancelMajor", LoginAuth)).Handle(new(controllers.Cancel))
		// mvc.New(api.Party("/privacyPolicy", LoginAuth)).Handle(new)
		// mvc.New(api.Party("/collegeScore", LoginAuth)).Handle(new(controller.))
		mvc.New(api.Party("/comment", LoginAuth)).Handle(new(controllers.Comment)) //老师获取评论历史记录

		mvc.New(api.Party("/yxs")).Handle(new(controllers.YxsController))

		// 后端
		mvc.New(api.Party("/authority-category", AdminUserAuth)).Handle(new(admin.AuthorityCategory))           // 权限分类
		mvc.New(api.Party("/admin-user-no-login")).Handle(new(admin.AdminUserNoLogin))                          // 不需要登录
		mvc.New(api.Party("/admin-user", AdminUserAuth)).Handle(new(admin.AdminUser))                           // 后台管理员
		mvc.New(api.Party("/authority", AdminUserAuth)).Handle(new(admin.Authority))                            // 权限
		mvc.New(api.Party("/admin/major", AdminUserAuth)).Handle(new(admin.Major))                              // 专业
		mvc.New(api.Party("/admin/university", AdminUserAuth)).Handle(new(admin.University))                    // 大学
		mvc.New(api.Party("/admin/college", AdminUserAuth)).Handle(new(admin.College))                          // 大学招生院校
		mvc.New(api.Party("/role", AdminUserAuth)).Handle(new(admin.Role))                                      // 管理员角色
		mvc.New(api.Party("/admin/major-category", AdminUserAuth)).Handle(new(admin.MajorCategory))             // 专业分类
		mvc.New(api.Party("/admin/rank", AdminUserAuth)).Handle(new(admin.Rank))                                // 位次
		mvc.New(api.Party("/admin/admission-data", AdminUserAuth)).Handle(new(admin.AdmissionData))             // 近2年专业录取数据
		mvc.New(api.Party("/admin/enrollment-plan", AdminUserAuth)).Handle(new(admin.EnrollmentPlanController)) // 招生计划
		mvc.New(api.Party("/admin/article", AdminUserAuth)).Handle(new(admin.ArticleController))                // 文章
		mvc.New(api.Party("/admin/article/category", AdminUserAuth)).Handle(new(admin.CategoryController))      // 文章分类
		mvc.New(api.Party("/admin/region", AdminUserAuth)).Handle(new(admin.Region))                            // 区域
		mvc.New(api.Party("/admin/student-score", AdminUserAuth)).Handle(new(admin.StudentScore))               // 学生成绩
		mvc.New(api.Party("/admin/feedback", AdminUserAuth)).Handle(new(admin.Feedback))                        // 反馈
		mvc.New(api.Party("/admin/user", AdminUserAuth)).Handle(new(admin.User))                                // 会员
		mvc.New(api.Party("/admin/site-config", AdminUserAuth)).Handle(new(admin.SiteConfig))                   // 网站配置
		mvc.New(api.Party("/admin/high-school", AdminUserAuth)).Handle(new(admin.HighSchool))                   // 高中
		mvc.New(api.Party("/admin/high-school-class", AdminUserAuth)).Handle(new(admin.HighSchoolClass))        // 高中班级
		mvc.New(api.Party("/admin/label", AdminUserAuth)).Handle(new(admin.Label))                              // 标签
		mvc.New(api.Party("/admin/college-level", AdminUserAuth)).Handle(new(admin.CollegeLevel))               // 院校标签
		mvc.New(api.Party("/admin/trends", AdminUserAuth)).Handle(new(admin.Trends))                            // 动态
		mvc.New(api.Party("/admin/comment", AdminUserAuth)).Handle(new(admin.Comment))                          // 动态评论
	}

	b.Get("/socket", websocket.Handler(chat.GetWs())) // 群里、单聊地址
}

// 后端登录验证
func AdminUserAuth(ctx iris.Context) {
	session := sessions.Get(ctx)
	p := ctx.Path()
	p = strings.ReplaceAll(p, "/", "")
	p = strings.ReplaceAll(p, "-", "")
	p = strings.Replace(p, "api", "", 3)
	fmt.Println(p)
	adminUserId, err := session.GetInt64("adminUserId")
	if err != nil || adminUserId <= 0 {
		ctx.JSON(map[string]interface{}{"code": 1001, "message": "还没登录，请求失败"})
		return
	}

	db, err := datasourse.NewMasterOrm()
	if err != nil {
		ctx.JSON(map[string]interface{}{"code": 1001, "message": fmt.Sprintf("连接数据库出错:%s", err.Error())})
		return
	}

	adminUser := new(models.Admin)
	ok, err := db.Id(adminUserId).Get(adminUser)
	if err != nil {
		ctx.JSON(map[string]interface{}{"code": 1001, "message": fmt.Sprintf("获取管理员信息失败:%s", err.Error())})
		return
	}
	if !ok {
		ctx.JSON(map[string]interface{}{"code": 1001, "message": "获取管理员信息失败"})
		return
	}

	role := new(models.Role)
	ok, err = db.Id(adminUser.RoleId).Get(role)
	if err != nil {
		ctx.JSON(map[string]interface{}{"code": 1001, "message": fmt.Sprintf("获取管理员角色信息失败:%s", err.Error())})
		return
	}
	if !ok {
		ctx.JSON(map[string]interface{}{"code": 1001, "message": "获取管理员角色信息失败"})
		return
	}

	if !strings.EqualFold(role.Authorities, "admin") {
		if !strings.Contains(role.Authorities, p) {
			ctx.JSON(map[string]interface{}{"code": 1001, "message": "抱歉，您没有操作权限"})
			return
		}
	}

	ctx.Next()
}

// 登录验证
func LoginAuth(ctx iris.Context) {
	var userId int64
	session := sessions.Get(ctx)

	channel := ctx.PostValue("channel")
	if len(channel) <= 0 {
		ctx.JSON(map[string]interface{}{"code": 1000, "message": "请提供渠道"})
		return
	}

	if channel == "wechat" {
		token := ctx.GetHeader("token")
		//解析token
		claims, err := utils.ParseToken(token)
		if err != nil {
			ctx.JSON(map[string]interface{}{"code": 20001, "message": "解析token有误"})
		}

		if claims.Id == "" {
			ctx.JSON(map[string]interface{}{"code": 20001, "message": "您还没有登录"})
			return
		}
	} else {
		userId, _ = session.GetInt64(fmt.Sprintf("%sUserId", channel))
		if userId <= 0 {
			ctx.JSON(map[string]interface{}{"code": 20001, "message": "您还没有登录"})
			return
		}

	}

	ctx.Next()
}
